package com.google.memoryofaplace;

import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;

import javax.jdo.PersistenceManager;

import com.beoui.geocell.GeocellManager;
import com.beoui.geocell.model.BoundingBox;
import com.beoui.geocell.model.Point;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.SortDirection;
import com.google.appengine.repackaged.org.json.JSONArray;
import com.google.appengine.repackaged.org.json.JSONException;
import com.google.appengine.repackaged.org.json.JSONObject;
import com.google.memoryofaplace.model.TBJQueryParams;
import com.google.memoryofaplace.model.TBPlaceMedia;
import com.google.memoryofaplace.model.TBPlaces;

public class BLPlaces {

	
	public static JSONObject createPlace(String arg0, String arg1, String arg2,
			String arg3, String arg4, String arg5, String arg6, String arg7,
			String arg8, String arg9, String arg10, String arg11) throws JSONException {
		JSONObject jReturn = new JSONObject();
		try {

			Double distance = General.distanceFromCenterArea(
					Double.parseDouble(arg5), Double.parseDouble(arg6));

			if (distance > General.MAX_DISTANCE_FROM_CENTER) {
				DecimalFormat df = new DecimalFormat("#");
				jReturn = General
						.returnError("Max distance from L'Aquila center is "
								+ General.MAX_DISTANCE_FROM_CENTER
								+ "m your place is located a distance "
								+ df.format(distance)
								+ "m from L'Aquila center");
			} else {
				PersistenceManager pm = PMF.get().getPersistenceManager();
				TBPlaces TBPlace = new TBPlaces(arg0, arg1,
						Integer.parseInt(arg2), Integer.parseInt(arg3),
						Integer.parseInt(arg4), Double.parseDouble(arg5),
						Double.parseDouble(arg6), arg7, arg8, arg9, arg10,arg11);
				pm.makePersistent(TBPlace);
				pm.close();

				jReturn.put("status", General.OK);
				jReturn.put("date", General.formatDate(new Date()));
				jReturn.put("codPlace", TBPlace.getCodPlace());
			}
		} catch (Exception e) {
			jReturn = new JSONObject();
			jReturn = General.returnError(e.getMessage());
		}
		return jReturn;
	}

	public static JSONObject updatePlace(String arg0, String arg1, String arg2,
			String arg3, String arg4, String arg5, String arg6, String arg7,
			String arg8, String arg9, String arg10, String arg11, String arg12)
			throws JSONException {
		JSONObject jReturn = new JSONObject();
		try {
			PersistenceManager pm = PMF.get().getPersistenceManager();

			TBPlaces place = pm.getObjectById(TBPlaces.class,
					KeyFactory.createKey("TBPlaces", Long.parseLong(arg0)));

			if (place == null) {
				jReturn = General.returnError("Place not found");
			} else {
				if (arg1 != null)
					place.setName(arg1);
				if (arg2 != null)
					place.setDescription(arg2);
				if (arg3 != null)
					place.setType(Integer.parseInt(arg3));
				if (arg4 != null)
					place.setStatus(Integer.parseInt(arg4));
				if (arg5 != null)
					place.setCategoryType(Integer.parseInt(arg5));
				if (arg6 != null)
					place.setLatitude(Double.parseDouble(arg6));
				if (arg7 != null)
					place.setLongitude(Double.parseDouble(arg7));
				if (arg8 != null)
					place.setUrlStreetView(arg8);
				if (arg9 != null)
					place.setUrl(arg9);
				if (arg10 != null)
					place.setUrlLogo(arg10);
				if (arg11 != null)
					place.setUserUpdate(arg11);
				if (arg12 != null)
					place.setAddress(arg12);
				
				place.setUpdate(new Date());
				if (place.getGeoCells().isEmpty()) {
					Point p = new Point(place.getLatitude(),
							place.getLongitude());
					List<String> cells = GeocellManager.generateGeoCell(p);
					place.setGeoCells(cells);
				}
			}
			pm.makePersistent(place);
			pm.close();

			jReturn.put("status", General.OK);
			jReturn.put("date", General.formatDate(new Date()));
			jReturn.put("codPlace", place.getCodPlace());
		} catch (Exception e) {
			jReturn = new JSONObject();
			jReturn = General.returnError(e.getMessage());
		}
		return jReturn;
	}

	public static JSONObject getPlaces() throws JSONException {
		JSONObject jResult = new JSONObject();
		try {
			DatastoreService datastoreService = DatastoreServiceFactory
					.getDatastoreService();
			Query q = new Query("TBPlaces");
			q.addFilter("status", Query.FilterOperator.EQUAL,
					Codes.Status.PUBLISHED.getCode());

			JSONArray jPlaces = new JSONArray();
			int i = 0;
			for (Entity event : datastoreService.prepare(q).asIterable()) {
				i++;
				jPlaces.put(getJSONEvent(event, true));
			}
			jResult.put("status", General.OK);
			jResult.put("date", General.formatDate(new Date()));
			jResult.put("results", jPlaces);
		} catch (Exception e) {
			jResult = new JSONObject();
			jResult = General.returnError(e.getMessage());
		}
		return jResult;
	}

	public static JSONObject getPlaces(double latN, double lonE, double latS,
			double lonW) throws JSONException {
		JSONObject jResult = new JSONObject();
		try {

			BoundingBox bb = new BoundingBox(latN, lonE, latS, lonW);
			// Calculate the geocells list to be used in the queries (optimize
			// list of cells that complete the given bounding box)
			List<String> cells = GeocellManager.bestBboxSearchCells(bb, null);

			PersistenceManager pm = PMF.get().getPersistenceManager();

			String queryString = "select from " + TBPlaces.class.getName()
					+ " where geocellsParameter.contains(geoCells)";
			javax.jdo.Query query = pm.newQuery(queryString);
			query.declareParameters("String geocellsParameter");

			@SuppressWarnings("unchecked")
			List<TBPlaces> places = (List<TBPlaces>) query.execute(cells);

			JSONArray jPlaces = new JSONArray();

			if (places != null) {
				for (TBPlaces place : places) {
					jPlaces.put(getJSONEvent(place, true));
				}
			}
			jResult.put("status", General.OK);
			jResult.put("date", General.formatDate(new Date()));
			jResult.put("results", jPlaces);
		} catch (Exception e) {
			jResult = new JSONObject();
			jResult = General.returnError(e.getMessage());
		}
		return jResult;
	}

	public static JSONObject getPlaces(double latN, double lonE, double latS,
			double lonW, int page) throws JSONException {
		JSONObject jResult = new JSONObject();
		try {

			BoundingBox bb = new BoundingBox(latN, lonE, latS, lonW);
			// Calculate the geocells list to be used in the queries (optimize
			// list of cells that complete the given bounding box)
			List<String> cells = GeocellManager.bestBboxSearchCells(bb, null);

			Query q = new Query("TBPlaces");
			q.addFilter("geoCells", Query.FilterOperator.IN, cells);
			DatastoreService datastoreService = DatastoreServiceFactory
					.getDatastoreService();

			
			
			
			FetchOptions fetchOptions;
			fetchOptions = FetchOptions.Builder.withLimit(
					General.MAX_QUERY_ROWS_PLACES_NEAR).offset(
					(page - 1) * General.MAX_QUERY_ROWS_PLACES_NEAR);
			JSONArray jResults = new JSONArray();
			for (Entity place : datastoreService.prepare(q).asIterable(
					fetchOptions)) {				
				jResults.put(getJSONEvent(place, true));
			}

			jResult.put("results", jResults);
			@SuppressWarnings("deprecation")
			int numTotal = datastoreService.prepare(q).countEntities();
			jResult.put("total", numTotal);
			jResult.put("page", page);
			int numPaginas = (numTotal / General.MAX_QUERY_ROWS_PLACES_NEAR);
			int partialPages = ((numTotal % General.MAX_QUERY_ROWS_PLACES_NEAR) > 0) ? (1)
					: (0);
			jResult.put("totalpages", numPaginas + partialPages);
			jResult.put("status", General.OK);
			jResult.put("date", General.formatDate(new Date()));
		} catch (Exception e) {
			jResult = new JSONObject();
			jResult = General.returnError(e.getMessage());
		}
		return jResult;
	}

	public static JSONObject getPlace(long codPlace) throws JSONException {
		JSONObject jResult = new JSONObject();
		try {

			PersistenceManager pm = PMF.get().getPersistenceManager();
			TBPlaces place = pm.getObjectById(TBPlaces.class,
					KeyFactory.createKey("TBPlaces", codPlace));
			JSONArray jPlace = new JSONArray();
			if (place == null) {
				jResult = General.returnError("event " + codPlace
						+ " not found");
			} else {
				JSONObject aEvent = getJSONEvent(place, false);
				jPlace.put(aEvent);
			}
			pm.close();
			jResult.put("status", General.OK);
			jResult.put("date", General.formatDate(new Date()));
			jResult.put("results", jPlace);

		} catch (Exception e) {
			jResult = new JSONObject();
			jResult = General.returnError(e.getMessage());
		}
		return jResult;
	}

	public static JSONObject getPlaceExtended(long codPlace)
			throws JSONException {
		JSONObject jResult = new JSONObject();
		try {

			PersistenceManager pm = PMF.get().getPersistenceManager();
			TBPlaces place = pm.getObjectById(TBPlaces.class,
					KeyFactory.createKey("TBPlaces", codPlace));
			JSONArray jPlace = new JSONArray();
			if (place == null) {
				jResult = General.returnError("event " + codPlace
						+ " not found");
			} else {
				JSONObject aEvent = getJSONEvent(place, false);
				jPlace.put(aEvent);
			}
			pm.close();
			jResult.put("status", General.OK);
			jResult.put("date", General.formatDate(new Date()));
			jResult.put("results", jPlace);

		} catch (Exception e) {
			jResult = new JSONObject();
			jResult = General.returnError(e.getMessage());
		}
		return jResult;
	}

	public static JSONObject getPlaceMedia(long codPlace, long codPlaceMedia)
			throws JSONException {
		JSONObject jResult = new JSONObject();
		try {

			PersistenceManager pm = PMF.get().getPersistenceManager();
			Key parent = KeyFactory.createKey("TBPlaces", codPlace);
			Key child = null;

			child = KeyFactory.createKey(parent, "TBPlaceMedia", codPlaceMedia);
			TBPlaceMedia placeMedia = pm.getObjectById(TBPlaceMedia.class,
					child);

			JSONArray jPlace = new JSONArray();
			if (placeMedia == null) {
				jResult = General.returnError("event " + codPlaceMedia
						+ " not found");
			} else {
				JSONObject jPlaceMedia = new JSONObject();

				jPlaceMedia.put("creation",
						General.formatDate(placeMedia.getCreation()));
				jPlaceMedia.put("title", placeMedia.getTitle());
				jPlaceMedia.put("thumbnail", placeMedia.getThumbnail());
				jPlaceMedia.put("codplace", placeMedia.getCodPlaceMedia());
				jPlaceMedia.put("mediacontenttype",
						placeMedia.getMediaContentType());
				jPlaceMedia.put("description", placeMedia.getDescription());
				jPlaceMedia.put("codplacemedia", placeMedia.getCodPlaceMedia());
				jPlaceMedia.put("taken",
						General.formatDate(placeMedia.getTaken(), "yyyy"));
				jPlaceMedia.put("user", placeMedia.getUser());
				jPlaceMedia.put("mediatype", placeMedia.getMediaType());
				jPlaceMedia.put("url", placeMedia.getUrl());
				jPlace.put(jPlaceMedia);
			}
			pm.close();
			jResult.put("status", General.OK);
			jResult.put("date", General.formatDate(new Date()));
			jResult.put("results", jPlace);

		} catch (Exception e) {
			jResult = new JSONObject();
			jResult = General.returnError(e.getMessage());
		}
		return jResult;
	}

	private static JSONObject getJSONEvent(TBPlaces place, boolean bLightFormat) {
		JSONObject jPlace = new JSONObject();
		try {
			jPlace.put("codplace", place.getCodPlace());
			jPlace.put("latitude", place.getLatitude());
			jPlace.put("longitude", place.getLongitude());

			jPlace.put("numcomments", place.getComments() == null ? 0 : place
					.getComments().size());
			jPlace.put("urlLogo", place.getUrlLogo());
			jPlace.put("urlStreetView", place.getUrlStreetView());
			jPlace.put("name", General.sanitize((String) (place.getName())));
			jPlace.put("description",
					General.sanitize((String) (place.getDescription())));
			jPlace.put("creation", place.getCreation());
			jPlace.put("address",
					General.sanitize((String) (place.getAddress())));
			
			if (!bLightFormat) {
				jPlace.put("status", place.getStatus());
				jPlace.put("userUpdate", place.getUserUpdate());
				jPlace.put("creation", place.getCreation());
				jPlace.put("update", place.getUpdate());
				jPlace.put("url", place.getUrl());

				jPlace.put("userCreation", place.getUserCreation());
				jPlace.put("type", place.getType());
				jPlace.put("categorytype", place.getCategoryType());
			}

		} catch (JSONException e) {

		}
		return jPlace;
	}

	public static JSONObject getJSONEvent(Entity place, Boolean bLightFormat) {
		JSONObject jPlace = new JSONObject();
		try {
			jPlace.put("codplace", place.getKey().getId());

			jPlace.put("latitude", place.getProperty("latitude"));
			jPlace.put("longitude", place.getProperty("longitude"));
			jPlace.put("numcomments", getNumComments(place.getKey().getId()));
			jPlace.put("urlStreetView", place.getProperty("urlStreetView"));
			jPlace.put("urlLogo", place.getProperty("urlLogo"));
			jPlace.put("name",
					General.sanitize((String) (place.getProperty("name"))));
			jPlace.put("description", General.sanitize((String) (place
					.getProperty("description"))));
			jPlace.put("creation", place.getProperty("creation"));
			jPlace.put("address", General.sanitize((String) place.getProperty("address")));			
			if (!bLightFormat) {
				jPlace.put("status", place.getProperty("status"));
				jPlace.put("userUpdate", place.getProperty("userUpdate"));
				jPlace.put("update", place.getProperty("update"));
				jPlace.put("url", place.getProperty("url"));
				jPlace.put("userCreation", place.getProperty("userCreation"));
				jPlace.put("type", place.getProperty("type"));
				jPlace.put("categorytype", place.getProperty("categoryType"));
			}
		} catch (JSONException e) {

		}

		return jPlace;
	}

	@SuppressWarnings("deprecation")
	public static long getNumComments(long codPlace) {
		long lReturn = 0;
		try {
			Query q = new Query("TBPlaceComments");
			Key placeKey = KeyFactory.createKey("TBPlaces", codPlace);
			q.setAncestor(placeKey);
			DatastoreService datastoreService = DatastoreServiceFactory
					.getDatastoreService();
			lReturn = datastoreService.prepare(q).countEntities();
		} catch (Exception e) {

		}
		return lReturn;
	}

	public static JSONObject getLastPlaces() throws JSONException {
		JSONObject jResult = new JSONObject();
		try {

			Query q = new Query("TBPlaces");
			q.addSort("creation", SortDirection.DESCENDING);
			DatastoreService datastoreService = DatastoreServiceFactory
					.getDatastoreService();
			FetchOptions fetchOptions;
			fetchOptions = FetchOptions.Builder
					.withLimit(General.MAX_QUERY_ROWS_CAROUSEL);
			JSONArray jResults = new JSONArray();
			for (Entity result : datastoreService.prepare(q).asIterable(
					fetchOptions)) {
				JSONObject jPlace = new JSONObject();
				jPlace.put("codplace", result.getKey().getId());
				jPlace.put("name", result.getProperty("name"));
				jPlace.put("urlStreetView", result.getProperty("urlStreetView"));
				jPlace.put("urlLogo", result.getProperty("urlLogo"));
				jPlace.put("creation", result.getProperty("creation"));
				jResults.put(jPlace);
			}

			jResult.put("results", jResults);
			jResult.put("total", jResults.length());
			jResult.put("status", General.OK);
			jResult.put("date", General.formatDate(new Date()));

		} catch (Exception e) {
			jResult = new JSONObject();
			jResult = General.returnError(e.getMessage());
		}

		return jResult;
	}

	// no se utiliza
	public static JSONObject getLastPlacesMedia() throws JSONException {
		JSONObject jResult = new JSONObject();
		try {

			Query q = new Query("TBPlaceMedia");
			q.addSort("creation", SortDirection.DESCENDING);
			DatastoreService datastoreService = DatastoreServiceFactory
					.getDatastoreService();
			FetchOptions fetchOptions;
			fetchOptions = FetchOptions.Builder
					.withLimit(General.MAX_QUERY_ROWS_CAROUSEL);
			JSONArray jResults = new JSONArray();
			for (Entity result : datastoreService.prepare(q).asIterable(
					fetchOptions)) {
				JSONObject jMedia = new JSONObject();
				jMedia.put("codplacemedia", result.getKey().getId());
				jMedia.put("user", result.getProperty("user"));
				jMedia.put("url", result.getProperty("url"));
				jMedia.put("thumbnail", result.getProperty("thumbnail"));
				jMedia.put("creation", General.formatDate((Date) result
						.getProperty("creation")));
				jMedia.put(
						"taken",
						General.formatDate(
								(Date) result.getProperty("creation"), "yyyy"));
				jMedia.put("title", result.getProperty("title"));
				jMedia.put("description", result.getProperty("description"));
				jMedia.put("mediatype", result.getProperty("mediaType"));
				jMedia.put("mediacontenttype",
						result.getProperty("mediaContentType"));
				jMedia.put("codplace", result.getParent().getId());
				jResults.put(jMedia);
			}

			jResult.put("results", jResults);
			jResult.put("total", jResults.length());
			jResult.put("status", General.OK);
			jResult.put("date", General.formatDate(new Date()));

		} catch (Exception e) {
			jResult = new JSONObject();
			jResult = General.returnError(e.getMessage());
		}

		return jResult;
	}

	public static JSONObject getPlaceMedia(Long codPlace, int page,
			int nMediaType) throws JSONException {
		JSONObject jResult = new JSONObject();
		try {

			Query q = new Query("TBPlaceMedia");
			Key keyPlace = KeyFactory.createKey("TBPlaces", codPlace);
			q.setAncestor(keyPlace);
			q.addSort("creation", SortDirection.DESCENDING);
			if (nMediaType != 0) {
				q.addFilter("mediaType", Query.FilterOperator.EQUAL, nMediaType);
			}

			DatastoreService datastoreService = DatastoreServiceFactory
					.getDatastoreService();
			FetchOptions fetchOptions;
			fetchOptions = FetchOptions.Builder.withLimit(
					General.MAX_QUERY_ROWS_PLACE_MEDIA).offset(
					(page - 1) * General.MAX_QUERY_ROWS_PLACE_MEDIA);
			JSONArray jResults = new JSONArray();
			for (Entity result : datastoreService.prepare(q).asIterable(
					fetchOptions)) {
				JSONObject jMedia = new JSONObject();
				jMedia.put("codplacemedia", result.getKey().getId());
				jMedia.put("user", result.getProperty("user"));
				jMedia.put("url", result.getProperty("url"));
				jMedia.put("thumbnail", result.getProperty("thumbnail"));
				jMedia.put("creation", General.formatDate((Date) result
						.getProperty("creation")));
				jMedia.put(
						"taken",
						General.formatDate(
								(Date) result.getProperty("creation"), "yyyy"));
				jMedia.put("title", result.getProperty("title"));
				jMedia.put("description", result.getProperty("description"));
				jMedia.put("mediatype", result.getProperty("mediaType"));
				jMedia.put("mediacontenttype",
						result.getProperty("mediaContentType"));
				// jMedia.put("codplace", result.getParent().getId());
				jResults.put(jMedia);
			}

			jResult.put("results", jResults);
			@SuppressWarnings("deprecation")
			int numTotal = datastoreService.prepare(q).countEntities();
			jResult.put("total", numTotal);
			jResult.put("page", page);
			int numPaginas = (numTotal / General.MAX_QUERY_ROWS_PLACE_MEDIA);
			int partialPages = ((numTotal % General.MAX_QUERY_ROWS_PLACE_MEDIA) > 0) ? (1)
					: (0);
			jResult.put("totalpages", numPaginas + partialPages);
			jResult.put("status", General.OK);
			jResult.put("date", General.formatDate(new Date()));
		} catch (Exception e) {
			jResult = new JSONObject();
			jResult = General.returnError(e.getMessage());
		}

		return jResult;
	}

	public static JSONObject getPlaceComments(Long codPlace, int page)
			throws JSONException {
		JSONObject jResult = new JSONObject();
		try {

			Query q = new Query("TBPlaceComments");
			Key keyPlace = KeyFactory.createKey("TBPlaces", codPlace);
			q.setAncestor(keyPlace);
			q.addSort("creation", SortDirection.DESCENDING);
			DatastoreService datastoreService = DatastoreServiceFactory
					.getDatastoreService();
			FetchOptions fetchOptions;
			fetchOptions = FetchOptions.Builder.withLimit(
					General.MAX_QUERY_ROWS_PLACE_COMMENTS).offset(
					(page - 1) * General.MAX_QUERY_ROWS_PLACE_COMMENTS);
			JSONArray jResults = new JSONArray();
			for (Entity result : datastoreService.prepare(q).asIterable(
					fetchOptions)) {
				JSONObject jComment = new JSONObject();
				jComment.put("codplacecomment", result.getKey().getId());
				jComment.put("user", result.getProperty("user"));
				jComment.put("comment", result.getProperty("comment"));
				jComment.put("commenttype", result.getProperty("commentType"));
				Long valor = (Long) result.getProperty("commentType");
				if (valor == 1) {

					jComment.put("image", getPlaceImage(codPlace));
				}
				jComment.put("creation", General.formatDate((Date) result
						.getProperty("creation")));
				jResults.put(jComment);
			}

			jResult.put("results", jResults);
			@SuppressWarnings("deprecation")
			int numTotal = datastoreService.prepare(q).countEntities();
			jResult.put("total", numTotal);
			jResult.put("page", page);
			int numPaginas = (numTotal / General.MAX_QUERY_ROWS_PLACE_COMMENTS);
			int partialPages = ((numTotal % General.MAX_QUERY_ROWS_PLACE_COMMENTS) > 0) ? (1)
					: (0);
			jResult.put("totalpages", numPaginas + partialPages);
			jResult.put("status", General.OK);
			jResult.put("date", General.formatDate(new Date()));
		} catch (Exception e) {
			jResult = new JSONObject();
			jResult = General.returnError(e.getMessage());
		}

		return jResult;
	}

	/**
	 * @param codPlace
	 * @return
	 */
	private static String getPlaceImage(Long codPlace) {
		String result = "";
		try {
			String strUrl = "";
			String strStreetView = "";
			PersistenceManager pm = PMF.get().getPersistenceManager();
			TBPlaces place = pm.getObjectById(TBPlaces.class,
					KeyFactory.createKey("TBPlaces", codPlace));
			if (place != null) {
				strUrl = place.getUrlLogo();
				strStreetView = place.getUrlStreetView();
			}
			if ((strUrl != null) && (strUrl != ""))
				return strUrl;
			if ((strStreetView != null) && (strStreetView != ""))
				return strStreetView;

			pm.close();
		} catch (Exception e) {

		}
		return result;

	}

	@SuppressWarnings("deprecation")
	public static JSONObject getAjaxPlaceMedia(TBJQueryParams params) {
		String sEcho = params.sEcho;
		String[] columns = { "codPlaceMedia", "thumbnail", "url", "title",
				"description", "mediaType", "taken", "user","creation" };
		int iTotalRecords; // total number of records (unfiltered)
		int iTotalDisplayRecords;// value will be set when code filters
									// companies by keyword
		int sortColumnIndex = params.iSortColumnIndex;
		JSONArray data = new JSONArray(); // data that will be shown in the
											// table
		DatastoreService datastoreService = DatastoreServiceFactory
				.getDatastoreService();
		Query q = new Query("TBPlaceMedia");
		if (sortColumnIndex == 0)
			sortColumnIndex = 1;
		SortDirection sortDirection = params.sSortDirection.equals("asc") ? SortDirection.ASCENDING
				: SortDirection.DESCENDING;
		q.addSort(columns[sortColumnIndex], sortDirection);
		FetchOptions fetchOptions;
		int page = (params.iDisplayStart == 0) ? 0 : params.iDisplayStart
				/ params.iDisplayLength;		
		fetchOptions = FetchOptions.Builder.withLimit(params.iDisplayLength).offset(
				(page) * params.iDisplayLength);

		
		iTotalRecords = datastoreService.prepare(q).countEntities();
		iTotalDisplayRecords = iTotalRecords;

		JSONObject jsonResponse = null;
		try {
			jsonResponse = new JSONObject();

			jsonResponse.put("sEcho", sEcho);
			jsonResponse.put("iTotalRecords", iTotalRecords);
			jsonResponse.put("iTotalDisplayRecords", iTotalDisplayRecords);
			//jsonResponse.put("_page", page);
			//jsonResponse.put("_limit", params.iDisplayLength);
			//jsonResponse.put("_sorting", columns[sortColumnIndex] +  " - " + sortDirection.toString());

			for (Entity placeMedia : datastoreService.prepare(q).asIterable(
					fetchOptions)) {
				JSONArray row = new JSONArray();
				row.put(placeMedia.getKey().getId())
						.put(placeMedia.getProperty("thumbnail"))
						.put(placeMedia.getProperty("url"))
						.put(placeMedia.getProperty("title"))
						.put(placeMedia.getProperty("description").toString()
								.length() <= 140 ? placeMedia
								.getProperty("description") : placeMedia
								.getProperty("description").toString()
								.substring(0, 136)
								+ "...")
						.put(Codes.MediaType.find(
								(Long) placeMedia.getProperty("mediaType")).toString())
						.put(General.formatDate((Date) placeMedia
								.getProperty("taken")))
								.put(placeMedia.getProperty("user"))
						.put(General.formatDate((Date) placeMedia
								.getProperty("creation"))).put("");
				data.put(row);
			}
			jsonResponse.put("aaData", data);
		} catch (JSONException e) {
			return jsonResponse;
		}
		return jsonResponse;
	}
	
	@SuppressWarnings("deprecation")
	public static JSONObject getAjaxPlaces(TBJQueryParams params) {
		String sEcho = params.sEcho;
		String[] columns = { "codPlace", "name", "description", "type",
				"categoryType", "userCreation", "creation", "edit" };
		int iTotalRecords; // total number of records (unfiltered)
		int iTotalDisplayRecords;// value will be set when code filters
									// companies by keyword
		int sortColumnIndex = params.iSortColumnIndex;
		JSONArray data = new JSONArray(); // data that will be shown in the
											// table
		DatastoreService datastoreService = DatastoreServiceFactory
				.getDatastoreService();
		Query q = new Query("TBPlaces");
		if (sortColumnIndex == 0)
			sortColumnIndex = 1;
		SortDirection sortDirection = params.sSortDirection.equals("asc") ? SortDirection.ASCENDING
				: SortDirection.DESCENDING;
		q.addSort(columns[sortColumnIndex], sortDirection);
		FetchOptions fetchOptions;
		int page = (params.iDisplayStart == 0) ? 0 : params.iDisplayStart
				/ params.iDisplayLength;		
		fetchOptions = FetchOptions.Builder.withLimit(params.iDisplayLength).offset(
				(page) * params.iDisplayLength);

		
		iTotalRecords = datastoreService.prepare(q).countEntities();
		iTotalDisplayRecords = iTotalRecords;

		JSONObject jsonResponse = null;
		try {
			jsonResponse = new JSONObject();

			jsonResponse.put("sEcho", sEcho);
			jsonResponse.put("iTotalRecords", iTotalRecords);
			jsonResponse.put("iTotalDisplayRecords", iTotalDisplayRecords);
			//jsonResponse.put("_page", page);
			//jsonResponse.put("_limit", params.iDisplayLength);
			//jsonResponse.put("_sorting", columns[sortColumnIndex] +  " - " + sortDirection.toString());

			for (Entity event : datastoreService.prepare(q).asIterable(
					fetchOptions)) {
				JSONArray row = new JSONArray();
				row.put(event.getKey().getId())
						.put(event.getProperty("name"))
						.put(event.getProperty("description").toString()
								.length() <= 140 ? event
								.getProperty("description") : event
								.getProperty("description").toString()
								.substring(0, 136)
								+ "...")
						.put(Codes.PlaceType.find(
								(Long) event.getProperty("type")).toString())
						.put(Codes.PlaceCategoryType.find(
								(Long) event.getProperty("categoryType"))
								.toString())
						.put(event.getProperty("userCreation"))
						.put(General.formatDate((Date) event
								.getProperty("creation")));
				data.put(row);
			}
			jsonResponse.put("aaData", data);
		} catch (JSONException e) {
			return jsonResponse;
		}
		return jsonResponse;
	}
}
